package com.geekhalo.lego.plugin.support.util;

import com.geekhalo.lego.plugin.support.ui.MethodNamePair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiImportList;
import com.intellij.psi.PsiImportStatement;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;

public class Utils {

    public static final String DOMAIN = "domain";
    public static final String APP = "app";
    public static final String INFRA = "infra";

    public static VirtualFile findSourceFile(VirtualFile[] sourceRoots) {
        for (VirtualFile file : sourceRoots){
            if (file.getPath().contains("src/main/java")){
                return file;
            }
        }
        return null;
    }

    public static String domainPkgToApp(String domainPkg){
        return domainPkg.replace(DOMAIN, APP);
    }

    public static String domainPkgToInfra(String domainPkg) {
        return domainPkg.replace(DOMAIN, INFRA);
    }

    public static String createCommandRepositoryByAgg(String aggClass) {
        return aggClass + "CommandRepository";
    }

    @NotNull
    public static String createAbstractDomainEventByAgg(String aggClass) {
        return "Abstract" + aggClass + "Event";
    }

    @NotNull
    public static String createQueryApplicationByAgg(String aggClass) {
        return aggClass + "QueryApplication";
    }

    @NotNull
    public static String createQueryApplicationByView(String viewClass) {
        return removeView(viewClass) + "QueryApplication";
    }

    @NotNull
    public static String createCommandApplicationByAgg(String aggClass) {
        return aggClass + "CommandApplication";
    }

    @NotNull
    public static String createQueryRepositoryByAgg(String aggClass) {
        return aggClass + "QueryRepository";
    }

    @NotNull
    public static String createQueryRepositoryByView(String viewClass) {
        return removeView(viewClass) + "QueryRepository";
    }

    private static String removeView(String viewClass) {
        if (viewClass.endsWith("View")){
            int length = "View".length();
            return viewClass.substring(0, viewClass.length() - length);
        }
        return viewClass;
    }

    public static String createJpaCmdRepositoryImplByAgg(String aggClass) {
        return "JpaBased" + createCommandRepositoryByAgg(aggClass);
    }

    public static String createJpaCmdRepositoryImplByRepository(String repository) {
        return "JpaBased" + repository;
    }


    public static String createJpaQueryRepositoryImplByAgg(String aggClass) {
        return "JpaBased" + createQueryRepositoryByAgg(aggClass);
    }

    public static String createTableByEntity(String entity){
        return entity.replaceAll("(.)(\\p{Upper})", "$1_$2").toLowerCase();
    }

    public static String createJpaQueryRepositoryImplByRepository(String repository) {
        return "JpaBased" + repository;
    }

    @NotNull
    public static String createDomainEventTypeName(MethodNamePair methodNamePair) {
        return methodNamePair.getTarget() + methodNamePair.getPastAction() + "Event";
    }

    @NotNull
    public static String createContextTypeName(MethodNamePair methodNamePair) {
        return methodNamePair.getAction() + methodNamePair.getTarget() + "Context";
    }

    @NotNull
    public static String createCommandTypeName(MethodNamePair methodNamePair) {
        return methodNamePair.getAction() + methodNamePair.getTarget() + "Command";
    }

    public static String getEnumJpaConvertName(String enumName) {
        return enumName + "Converter";
    }

    public static String getEnumMyBatisConvertName(String enumName) {
        return enumName + "Handler";
    }

    public static boolean isObjectMethod(PsiMethod psiMethod) {
        PsiClass containingClass = psiMethod.getContainingClass();
        if (containingClass != null && "Object".equals(containingClass.getName())) {
            return true;
        }
        return false;
    }

    public static String getBeanName(String fullType) {
        String clsName = fullType;
        if (clsName.contains(".")) {
            clsName = clsName.substring(clsName.lastIndexOf(".") + 1);
        }
        return Character.toLowerCase(clsName.charAt(0)) + clsName.substring(1);
    }

    public static String getType(String fullType){
        if (fullType.contains(".")) {
            return fullType.substring(fullType.lastIndexOf('.') + 1);
        }
        return fullType;
    }

    public static String getPkg(String fullType){
        return fullType.substring(0, fullType.lastIndexOf('.'));
    }

    public static String createFactoryName(String cxtTypeFull) {
        return getType(cxtTypeFull) + "Factory";
    }

    public static String createConverterName(String name) {
        return name + "Converter";
    }

    public static String createViewByAgg(String aggClass) {
        return aggClass + "View";
    }

    public static String getTypeFromClass(String text) {
        return text.replace(".class", "").replace(".java","");
    }

    public static boolean hasImports(PsiImportList importList, PsiClass psiClass) {
        return Arrays.asList(importList.getImportStatements())
                .stream()
                .map(PsiImportStatement::getQualifiedName)
                .anyMatch(qualifiedName ->
                        psiClass.getQualifiedName().equals(qualifiedName)
                );
    }
}
